package com.example.dw.controller;

import com.example.dw.common.Result;
import com.example.dw.dto.*;
// import com.example.dw.entity.AboutMe;
import com.example.dw.entity.Pack;
import com.example.dw.service.UserService;
import com.example.dw.vo.UserVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * 用户控制器
 * @author system
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/user")
@Tag(name = "用户管理", description = "用户相关的API接口")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 用户注册
     * @param userRegisterDTO 用户注册请求数据
     * @return 注册结果
     */
    @PostMapping("/register")
    @Operation(summary = "用户注册", description = "新用户注册接口")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "注册成功"),
            @ApiResponse(responseCode = "400", description = "注册失败")
    })
    public Result<String> register(@Validated @RequestBody UserRegisterDTO userRegisterDTO) {
        try {
            userService.register(userRegisterDTO);
            return Result.success("注册成功");
        } catch (Exception e) {
            log.error("用户注册失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 用户登录
     */
    @PostMapping("/login")
    @Operation(summary = "用户登录", description = "用户账号密码登录")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "登录成功"),
            @ApiResponse(responseCode = "400", description = "登录失败")
    })
    public Result<Map<String, Object>> login(
            @Parameter(description = "用户登录信息") @Validated @RequestBody UserLoginDTO loginDTO) {
        try {
            Map<String, Object> result = userService.login(loginDTO);
            return Result.success("登录成功", result);
        } catch (Exception e) {
            log.error("用户登录失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 验证码登录
     */
    @PostMapping("/login/code")
    @Operation(summary = "验证码登录", description = "使用手机号和验证码登录")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "登录成功"),
            @ApiResponse(responseCode = "400", description = "验证码错误或登录失败")
    })
    public Result<Map<String, Object>> codeLogin(
            @Parameter(description = "验证码登录信息") @Validated @RequestBody CodeLoginDTO codeLoginDTO) {
        try {
            Map<String, Object> result = userService.codeLogin(codeLoginDTO);
            return Result.success("登录成功", result);
        } catch (Exception e) {
            log.error("验证码登录失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 微信登录
     */
    @PostMapping("/wechat/login")
    @Operation(summary = "微信登录", description = "使用微信授权码登录")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "登录成功"),
            @ApiResponse(responseCode = "400", description = "微信授权失败")
    })
    public Result<Map<String, Object>> wechatLogin(
            @Parameter(description = "微信授权码") @RequestParam String code) {
        try {
            Map<String, Object> result = userService.wechatLogin(code);
            return Result.success("登录成功", result);
        } catch (Exception e) {
            log.error("微信登录失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 获取用户信息
     */
    @GetMapping("/user")
    @Operation(summary = "获取当前用户信息", description = "获取当前登录用户的详细信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问")
    })
    public Result<UserVO> getCurrentUserInfo(HttpServletRequest request) {
        try {
            Integer userid = getCurrentUserId(request);
            UserVO userVO = userService.getUserInfo(userid);
            return Result.success(userVO);
        } catch (Exception e) {
            log.error("获取用户信息失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 更新用户信息
     */
    @PutMapping("/user")
    @Operation(summary = "更新当前用户信息", description = "更新当前登录用户的个人信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "更新成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "400", description = "参数验证失败")
    })
    public Result<Void> updateCurrentUserInfo(HttpServletRequest request, 
                                              @Parameter(description = "用户信息更新数据") @Validated @RequestBody UpdateUserInfoDTO updateUserInfoDTO) {
        try {
            Integer userid = getCurrentUserId(request);
            userService.updateUserInfo(userid, updateUserInfoDTO);
            return Result.success("更新成功");
        } catch (Exception e) {
            log.error("更新用户信息失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 修改密码
     */
    @PutMapping("/user/password")
    @Operation(summary = "修改用户密码", description = "修改当前用户的登录密码")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "密码修改成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "400", description = "原密码错误")
    })
    public Result<Void> changeUserPassword(HttpServletRequest request,
                                           @Parameter(description = "原密码") @RequestParam String oldPassword,
                                           @Parameter(description = "新密码") @RequestParam String newPassword) {
        try {
            Integer userid = getCurrentUserId(request);
            userService.updatePassword(userid, oldPassword, newPassword);
            return Result.success("密码修改成功");
        } catch (Exception e) {
            log.error("修改密码失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 用户签到
     */
    @PostMapping("/user/sign")
    @Operation(summary = "用户每日签到", description = "用户每日签到打卡")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "签到成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "400", description = "今日已签到")
    })
    public Result<Void> userDailySignIn(HttpServletRequest request) {
        try {
            Integer userid = getCurrentUserId(request);
            userService.sign(userid);
            return Result.success("签到成功");
        } catch (Exception e) {
            log.error("签到失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 今日签到状态
     */
    @GetMapping("/user/signStatus")
    @Operation(summary = "获取今日签到状态", description = "查询用户今日是否已签到")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问")
    })
    public Result<Boolean> getTodaySignInStatus(HttpServletRequest request) {
        try {
            Integer userid = getCurrentUserId(request);
            Boolean status = userService.signStatus(userid);
            return Result.success(status);
        } catch (Exception e) {
            log.error("获取签到状态失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 获取教师列表
     */
    @GetMapping("/teacher")
    @Operation(summary = "获取所有教师列表", description = "获取系统中所有教师的基本信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取成功")
    })
    public Result<List<UserVO>> getAllTeacherList() {
        try {
            List<UserVO> teachers = userService.getTeacherList();
            return Result.success(teachers);
        } catch (Exception e) {
            log.error("获取教师列表失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 分页获取教师列表
     */
    @PostMapping("/teacher")
    @Operation(summary = "分页获取教师列表", description = "分页获取系统中教师信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取成功")
    })
    public Result<Map<String, Object>> getTeacherListByPage(@Parameter(description = "页码，从1开始", example = "1") @RequestParam(defaultValue = "1") Integer page,
                                                            @Parameter(description = "每页大小", example = "10") @RequestParam(defaultValue = "10") Integer size) {
        try {
            Map<String, Object> result = userService.getTeacherListPage(page, size);
            return Result.success(result);
        } catch (Exception e) {
            log.error("分页获取教师列表失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 绑定手机号
     */
    @PostMapping("/photo/bind")
    @Operation(summary = "绑定手机号", description = "用户绑定或更换手机号")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "绑定成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "400", description = "验证码错误")
    })
    public Result<Void> bindUserPhoneNumber(HttpServletRequest request,
                                            @Parameter(description = "手机号码") @RequestParam String phone,
                                            @Parameter(description = "验证码") @RequestParam String code) {
        try {
            Integer userid = getCurrentUserId(request);
            userService.bindPhone(userid, phone, code);
            return Result.success("绑定成功");
        } catch (Exception e) {
            log.error("绑定手机号失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 获取关于我们信息
     * @return 关于我们信息
     */
    /*
    @GetMapping("/user/aboutMe")
    public Result<AboutMe> getAboutMe() {
        log.info("获取关于我们信息");
        AboutMe aboutMe = userService.getAboutMe();
        return Result.success(aboutMe);
    }
    */

    /**
     * 获取用户协议
     */
    @GetMapping("/user/pack")
    @Operation(summary = "获取用户协议", description = "获取平台用户协议内容")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取成功")
    })
    public Result<Pack> getUserAgreement() {
        try {
            Pack pack = userService.getPack();
            return Result.success(pack);
        } catch (Exception e) {
            log.error("获取用户协议失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 绑定微信
     */
    @PostMapping("/bindWechat")
    @Operation(summary = "绑定微信账号", description = "将微信账号绑定到当前用户")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "绑定成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "400", description = "微信授权失败")
    })
    public Result<Void> bindWechatAccount(HttpServletRequest request, 
                                          @Parameter(description = "微信授权码") @RequestParam String code) {
        try {
            Integer userid = getCurrentUserId(request);
            userService.bindWechat(userid, code);
            return Result.success("绑定成功");
        } catch (Exception e) {
            log.error("绑定微信失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 获取用户打卡记录
     */
    @PostMapping("/user/DoKaRecord")
    @Operation(summary = "获取用户打卡记录", description = "分页获取当前用户的打卡签到记录")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问")
    })
    public Result<Map<String, Object>> getUserSignInRecords(HttpServletRequest request,
                                                            @Parameter(description = "页码，从1开始", example = "1") @RequestParam(defaultValue = "1") Integer page,
                                                            @Parameter(description = "每页大小", example = "10") @RequestParam(defaultValue = "10") Integer size) {
        try {
            Integer userid = getCurrentUserId(request);
            Map<String, Object> result = userService.getSignRecord(userid, page, size);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取打卡记录失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 生成登录二维码
     */
    @PostMapping("/auth/qrcode/generate")
    @Operation(summary = "生成登录二维码", description = "生成用于扫码登录的二维码token")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "生成成功")
    })
    public Result<String> generateQRCodeForLogin() {
        try {
            String qrToken = userService.generateLoginQR();
            return Result.success(qrToken);
        } catch (Exception e) {
            log.error("生成二维码失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 检查二维码状态
     */
    @PostMapping("/auth/qrcode/check")
    @Operation(summary = "检查二维码登录状态", description = "轮询检查二维码的扫码和登录状态")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "检查成功")
    })
    public Result<Map<String, Object>> checkQRCodeLoginStatus(@Parameter(description = "二维码token") @RequestParam String qrToken) {
        try {
            Map<String, Object> result = userService.checkLoginStatus(qrToken);
            return Result.success(result);
        } catch (Exception e) {
            log.error("检查二维码状态失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 小程序扫码后调用（绑定用户）
     */
    @PostMapping("/auth/qrcode/bind")
    @Operation(summary = "绑定二维码扫码", description = "小程序端扫码后绑定当前用户到二维码")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "绑定成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问")
    })
    public Result<Void> bindQRCodeToUser(HttpServletRequest request, 
                                         @Parameter(description = "二维码token") @RequestParam String qrToken) {
        try {
            Integer userid = getCurrentUserId(request);
            userService.bindScanToken(userid, qrToken);
            return Result.success("绑定成功");
        } catch (Exception e) {
            log.error("绑定二维码失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 小程序扫码后调用（已扫码）
     */
    @PostMapping("/auth/qrcode/binded")
    @Operation(summary = "确认二维码扫码", description = "用户确认扫码登录，完成二维码登录流程")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "确认成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问")
    })
    public Result<Void> confirmQRCodeScan(HttpServletRequest request, 
                                          @Parameter(description = "二维码token") @RequestParam String qrToken) {
        try {
            Integer userid = getCurrentUserId(request);
            userService.confirmScan(userid, qrToken);
            return Result.success("确认成功");
        } catch (Exception e) {
            log.error("确认扫码失败：{}", e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 从请求中获取当前用户ID
     */
    private Integer getCurrentUserId(HttpServletRequest request) {
        Integer userid = (Integer) request.getAttribute("userid");
        if (userid == null) {
            throw new RuntimeException("未授权访问");
        }
        return userid;
    }
} 